#include <semaphore.h>

#include "tmsxx.h"
#include <string.h>
#include "ep_app.h"
#include "stdio.h"
#include "epollserver.h"
#include "tms_app.h"
// #include "tmsxxdb.h"
#include "sys/wait.h"
// #include <strings.h>

#include "otdr_ch.h"
#include "hb_app.h"
#include "global.h"
#include "supplement.h"
#ifdef __cplusplus
extern "C" {
#endif
//通道的偏移量，CU通过通道来确定偏移来确定与哪一个otdr通信


int32_t OnGetBasicInfo(struct tms_context *pcontext)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	ret_host_basic_info(pcontext,NULL);
	return 0;
}

int32_t OnGetNodeTime(struct tms_context *pcontext)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	time_t t;
	struct tm *local; //本地时间
	char buf[20] = {0};
	struct tms_ack ack;
	int32_t ret;
	struct glink_addr addr;
	memset(&ack, 0, sizeof(struct tms_ack));
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;

	//该回调函数缺乏输入节点名称，需要woo配合修改
	ack.cmdid = pcontext->pgb->cmdid;

	t = time(NULL);
	if(t == 0){
		ret = CMD_RET_OTHRER_ERROR;
		goto fail_exit;
	}
	local = localtime(&t); //转为本地时间
	if(local == NULL){
		ret = CMD_RET_OTHRER_ERROR;
		goto fail_exit;
	}

	printf("%d-%d-%d %d:%d:%d\n",
			local->tm_hour, local->tm_mday, local->tm_wday,
			local->tm_hour, local->tm_min, local->tm_sec);

	strftime(buf, 20, "%Y-%m-%d %H:%M:%S", local);

	tms_RetNodeTime(pcontext, NULL, buf);
	printf("%s %d ret host time %s \n", __FUNCTION__, __LINE__, buf);
	//tms_MergeCurAlarm(g_201fd);
	if(otdrTestCtrl.is_send_alarm)
		ret_total_curalarm2host_V2(&addr);
	return 0;
fail_exit:
	ack.errcode = ret;
	tms_AckEx(pcontext->fd, &addr, &ack);	
	PR_X("error,t= %d local = %p",t,local);
	return 0;

}
int32_t OnRetNodeTime(struct tms_context *pcontext)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);

	return 0;
}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnNameAndAddress 处理收到节点名称和地址
 *
 * @param pcontext
 *
 * @returns   0成功，以及无法保存的命令
 */
/* ----------------------------------------------------------------------------*/
int32_t OnNameAndAddress(struct tms_context *pcontext, struct tms_nameandaddr *pval)
{
	struct tms_ack ack;
	int32_t ret;
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	memset(&ack, 0, sizeof(struct tms_ack));

	//该回调函数缺乏输入节点名称，需要woo配合修改
	ack.cmdid = pcontext->pgb->cmdid;
	memcpy(&devMisc.name, pval,sizeof(struct _tagDevNameAddr));
	ret = save_node_name_address(&devMisc);

	if(ret != CMD_RET_OK)
		ret = CMD_RET_CANT_SAVE;

	ack.errcode = ret;
	tms_AckEx(pcontext->fd, &addr, &ack);	

	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	return 0;
}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnFiberSectionCfg 主机配置光纤段参数
 *
 * @param pcontext	主机相关地址
 * @param pval		具体参数
 *
 * @returns   		0 ，参数非法，无法保存
 */
/* ----------------------------------------------------------------------------*/
int32_t OnFiberSectionCfg(struct tms_context *pcontext,struct tms_fibersectioncfg *pval)
{
	int32_t ret,ch;
	struct tms_ack ack;
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	memset(&ack, 0, sizeof(struct tms_ack));


	ack.cmdid = pcontext->pgb->cmdid;

	ret = check_fiber_sec_para(pval);

	if(ret != CMD_RET_OK)
		goto usr_exit;
	//host的通道是从1开始计数
	ch = pval->otdr_param->pipe - ch_offset;
	ret = save_fiber_sec_para(ch, pval,&chFiberSec[ch],&otdrDev[ch] );
	if(ret != CMD_RET_OK)
		ret = CMD_RET_CANT_SAVE;
	else
		ret_total_curalarm2host();

usr_exit:
	ack.errcode = ret;
	tms_AckEx(pcontext->fd, &addr, &ack);
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	return ret;
}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnConfigPipeState 主机配置通道使用状态
 *
 * @param pcontext
 * @param pval
 *
 * @returns   0，无法保存
 */
/* ----------------------------------------------------------------------------*/
int32_t OnConfigPipeState(struct tms_context *pcontext, struct tms_cfgpip_status *pval)
{
	int32_t ret;
	struct tms_ack ack;
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	memset(&ack, 0, sizeof(struct tms_ack));


	ack.cmdid = pcontext->pgb->cmdid;
	//第一机框，只八个通道，取低8位 第二个通道，取高8位
	if(ch_offset == 1)
		devMisc.ch_state.state = pval->status & 0x000000ff;
	else
		devMisc.ch_state.state = (pval->status & 0x0000ff00) >> 8;
	ret = save_node_name_address(&devMisc);
	if(ret != CMD_RET_OK){
		ret = CMD_RET_CANT_SAVE;
		printf("%s %d can't save para, ret %d \n", __FUNCTION__, __LINE__,ret);
	}
	else
		refresh_ch_state(devMisc.ch_state.state);
	ack.errcode = ret;
	tms_AckEx(pcontext->fd, &addr, &ack);

	// todo 该设备在本机框第几槽位，对应第几通道，写入配置文件
	printf("%s():%d state local 0x%x rcv 0x%x ch_offset %d\n", __FUNCTION__, __LINE__,\
			devMisc.ch_state, pval->status, ch_offset);

	return ret;
}
int32_t OnGetCycleTestCuv(struct tms_context *pcontext, struct tms_getcyctestcuv *pval)
{
	int ret, ch, slot;
	struct tms_ack ack;
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;

	slot = pval->slot;
	ch = pval->pipe;

	ack.cmdid = pcontext->pgb->cmdid;
	ret = CMD_RET_OK;
	ret = isValidSlot_Ch(slot, ch);
	printf("%s():%d slot (%d) ch (%d) \n", __FUNCTION__, __LINE__,slot,ch);

	if(ret != 0)
	{
		ret = CMD_RET_PARA_INVLADE;
		goto usr_exit;
	}

	ret_host_cyc_curv(pcontext, &otdrDev[ch].curv, ch);
usr_exit:
	if(ret != 0)
		tms_AckEx(pcontext->fd, &addr, &ack);
	return ret;
}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnGetStatusData 获取某通道的统计数据
 *
 * @param pcontext
 * @param pval
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
int32_t OnGetStatusData(struct tms_context *pcontext, struct tms_getstatus_data *pval)
{

	int ret, ch, slot;
	struct tms_ack ack;
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;

	slot = pval->slot;
	ch = pval->pipe;

	ack.cmdid = pcontext->pgb->cmdid;
	ret = CMD_RET_OK;
	ret = isValidSlot_Ch(slot, ch);
	printf("%s():%d slot (%d) ch (%d) \n", __FUNCTION__, __LINE__,slot,ch);

	if(ret != 0)
	{
		ret = CMD_RET_PARA_INVLADE;
		goto usr_exit;
	}

	ret_host_statis_data(ch, pcontext, &chFiberSec[ch]);
usr_exit:
	if(ret)
		tms_AckEx(pcontext->fd,&addr, &ack);
	return 0;
}
int32_t OnStatusData(struct tms_context *pcontext)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	return 0;
}
int32_t OnCRCCheckout(struct tms_context *pcontext)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	return 0;
}
int32_t OnCheckoutResult(struct tms_context *pcontext)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	return 0;
}
int32_t OnOTDRBasicInfo(struct tms_context *pcontext)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	return 0;
}
int32_t OnConfigNodeTime(struct tms_context *pcontext,struct tms_confignodetime *pval)
{
	struct tms_ack ack;
	char ctime[20] = {0};
	char strout[64] = {0};        
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	memset(&ack, 0, sizeof(struct tms_ack));

	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	memcpy(ctime, pval, 19);
	ctime[19] = '\0';  
	snprintf(strout, 64, "/bin/settime.sh \" %s\"", ctime);
	system(strout);
	ack.cmdid =  pcontext->pgb->cmdid;
	ack.errcode = 0;
	printf("%s %d %s \n", __FUNCTION__, __LINE__, strout);
	// TODO set time
	tms_AckEx(pcontext->fd, &addr, &ack);
	//ret_total_curalarm2host();
	return 0;
}
int32_t OnCurAlarm(struct tms_context *pcontext, struct tms_get_alarm *pval)
{
	int32_t ret, slot;
	struct glink_addr addr;
	struct tms_ack ack;


	ret = 0;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	slot = pval->slot;

	memset(&ack, 0, sizeof(ack));
	ack.cmdid = pcontext->pgb->cmdid;
	ack.type_pipe = 0;

	ret = isValidSlot_Ch(pval->slot, 0);

	if(ret){
		ret = CMD_RET_PARA_INVLADE ;
		goto usr_exit;
	}

	
	if(pval->slot != card_slot){
		ret = CMD_RET_PARA_INVLADE ;
		goto usr_exit;
	}
	ret_total_curalarm2host_V2(&addr);
usr_exit:
	if(ret != 0){
		ack.errcode = ret;
		tms_AckEx(pcontext->fd, &addr, &ack);
	}
	return 0;
}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnGetOTDRData 用户点名测量
 *
 * @param pcontext
 * @param pget_otdr_data
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
extern sem_t sem_UsrTest;
extern struct _tagOtdrTestCtrl otdrTestCtrl;
extern pthread_mutex_t mutex_measur;
extern struct _tagParalleCtrl *paralleCtrlBuf;
extern struct _tagUsrOtdrTest *usrOtdrTestBuf_P;
int32_t OnGetOTDRData(struct tms_context *pcontext,struct tms_get_otdrdata *pget_otdr_data)
{
	int ret,count,ch,*stop;
	struct tms_ack ack;
	struct glink_addr addr;
	struct _tagUsrOtdrTest *pusrOtdrTest;
	sem_t *psem_test;
	pthread_mutex_t *pmeasur_mutex;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;

	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	ch = pget_otdr_data->pipe;
	ack.cmdid = pcontext->pgb->cmdid;
	ack.type_pipe = ch;


	ret = check_usr_otdr_test_para(pget_otdr_data);
	if(ret != CMD_RET_OK)
		goto usr_exit;
	/*
	 * 并行otdr和串行otdr分开处理
	 * 本函数不返回，无法再次调用
	*/
	if(otdrTestCtrl.mod == OTDR_PARALLE)
	{
		stop = &paralleCtrlBuf[ch].stop;
		pmeasur_mutex = &paralleCtrlBuf[ch]. mutex_tsk;
		psem_test = &paralleCtrlBuf[ch].sem_appoint;
		pusrOtdrTest = &usrOtdrTestBuf_P[ch];
		otdrTestCtrl.apponit_ch = ch;

	}
	else
	{
		stop = &otdrTestCtrl.stop;
		pmeasur_mutex = &mutex_measur;
		psem_test = &sem_UsrTest;
		pusrOtdrTest = &usrOtdrTest;
	}
	//正在累加中，不能响应用户的测量需求
	if(pusrOtdrTest->state != USR_OTDR_TEST_IDLE){
		ret = CMD_RET_EXIST_CMD;
		goto usr_exit;
	}
	//给点名测量传递参数, 维纳迪增加了osw 信息，端口号与通道类同
	memcpy(&pusrOtdrTest->para.MeasureLength_m, &pget_otdr_data->range, sizeof(struct _tagHostOtdrPara) - 8);
	memcpy(&pusrOtdrTest->osw, &pget_otdr_data->osw, sizeof(struct tms_dev_desc));
	pusrOtdrTest->para.pipe = pget_otdr_data->pipe;
	pusrOtdrTest->para.slot = card_slot;

	pusrOtdrTest->cmd = ack.cmdid;
	pusrOtdrTest->src_addr.src = pcontext->pgb->src;
	pusrOtdrTest->src_addr.pkid = pcontext->pgb->pkid;
	pusrOtdrTest->src_addr.dst = pcontext->pgb->dst;
	pusrOtdrTest->state = USR_OTDR_TEST_WAIT;
	count = 0;
	while(pthread_mutex_trylock(pmeasur_mutex) != 0){
		count++;
		*stop = 1;
		//3秒钟
		if(count >= 30000){
			PR_X("can't get lock\n");
			ret = CMD_RET_EXIST_CMD;
			pusrOtdrTest->state = USR_OTDR_TEST_IDLE;
			goto usr_exit;
		}
		usleep(100);

	}
	sem_post(psem_test);
	pthread_mutex_unlock(pmeasur_mutex);

usr_exit:
	//如果超时退出之后，将stop重新设置成0
	if(*stop == 1)
		*stop = 0;
	ack.errcode = ret;
	tms_AckEx(pcontext->fd,&addr, &ack);
	return ret;
}

/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnGetStandardCurv 获取标准曲线
 *
 * @param pcontext
 * @param pval
 *
 * @returns   标准曲线
 */
/* ----------------------------------------------------------------------------*/
int32_t OnGetStandardCurv(struct tms_context *pcontext, struct tms_getstandardcurv *pval)
{
	int ret, ch;
	struct tms_ack ack;
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;

	ack.cmdid = pcontext->pgb->cmdid;

	ret = CMD_RET_OK;
	ch = pval->pipe - ch_offset;
	printf("%s %d ch %d \n", __FUNCTION__, __LINE__, pval->pipe);
	if(ch < 0 || ch > CH_NUM)
	{
		ret = CMD_RET_PARA_INVLADE;
		ack.errcode = ret;
		goto usr_exit;
	}
	//ret_host_std_curv(pcontext, &chFiberSec[ch],ch);
usr_exit:
	if(ret)
		tms_AckEx(pcontext->fd,&addr, &ack);
	return 0;
}
int32_t OnSetOTDRFPGAInfo(struct tms_context *pcontext, struct tms_setotdrfpgainfo *pval)
{
	printf("%s %d undefine op \n", __FUNCTION__, __LINE__);
	return 0;

}
int32_t OnGetOTDRFPGAInfo(struct tms_context *pcontext)
{
	int32_t ret, ch, slot;
	struct tms_setotdrfpgainfo fpga_para;
	struct tms_ack ack;
	struct glink_addr addr;

	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;

	memset(&ack, 0, sizeof(struct tms_ack));

	ack.cmdid = pcontext->pgb->cmdid;
	ret = 0;


	tms_RetFpgaInfo(pcontext, &addr, &fpga_para, CH_NUM);
usr_exit:
	if(ret)
	{
		ack.errcode = ret;
		tms_AckEx(pcontext->fd, &addr, &ack);
	}
		
}
int32_t OnSetOCVMPara(struct tms_context *pcontext, struct tms_setocvmpara *pval)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	hb2_dbg("cable_len	%f"
			"host_thr	%d"
			"slave_thr	%d"
			"amend		%f\n",
			pval->cable_len,
			pval->host_thr,
			pval->slave_thr,
			pval->amend);
	return 0;
}

int32_t OnSetOCVMFPGAInfo(struct tms_context *pcontext, struct tms_setocvmfpgainfo *pval)
{
	trace_dbg("%s():%d\n", __FUNCTION__, __LINE__);
	hb2_dbg("max cable len	%f"
			"wl	%s\n",
			pval->max_cable_len,
			pval->wl);
	return 0;
}

int32_t OnGetDevType(struct tms_context *pcontext)
{
	int32_t ret;
	struct glink_addr addr;
	struct tms_ret_card_type card_type;

	memset(&card_type, 0, sizeof(struct tms_ret_card_type));
	card_type.frame = card_frame;
	card_type.slot = card_slot;
	card_type.type = LOCAL_CARD_TYPE;
	card_type.ports = CH_NUM;
	card_type.rsv[0] = otdrTestCtrl.mod;

	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;


	ret = tms_RetDevType(pcontext, &addr, &card_type);
	return 0;
}
int32_t OnRcvNetSwitch(struct tms_context *pcontext)
{
	int32_t ret, fd;
	struct tms_ack ack;
	struct glink_addr addr;

	fd = pcontext->fd;

	ack.cmdid = pcontext->pgb->cmdid;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
       	addr.pkid = pcontext->pgb->pkid;
	ack.errcode = 0;
	tms_AckEx(fd, &addr, &ack);

	return 0;
}
int32_t OnRcvNMState(struct tms_context *pcontext, int32_t state) 
{
	int32_t ret, fd;
	struct tms_ack ack;
	struct glink_addr addr;

	fd = pcontext->fd;

	ack.cmdid = pcontext->pgb->cmdid;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
       	addr.pkid = pcontext->pgb->pkid;
	ack.errcode = 0;
	tms_AckEx(fd, &addr, &ack);

}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnGetSoftv 获取版本号，包含编译日期，cpu类型，fpga版本
 *
 * @param pcontext
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
int32_t OnGetSoftv(struct tms_context *pcontext)
{
	int32_t ret;
	int32_t index;
	struct glink_addr addr;
	char *pbuf, *palarm_v;
	struct tms_soft_version sfv;
	struct fpga_info *pinfo;
	pinfo = &fpga_device_info;

	memset(&sfv, 0, sizeof(struct tms_soft_version));

	sfv.frame = card_frame;
	sfv.slot = card_slot;
	sfv.type = LOCAL_CARD_TYPE;
	
	//编译时间
	strncpy(sfv.version,BUILD_DATE,19);
	index = 19;
	//设备类型cpu
	strncpy(sfv.version + index, "-otdr:28x-",10);
	index += 10;
	//fpga信息
	pbuf = sfv.version + index;
	snprintf(pbuf, 18,"0x-%x-%x-%x",\
			pinfo->hw_ver,pinfo->ch, pinfo->soft_ver);
	index += strlen(pbuf);


	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;

	tms_RetSoftv(pcontext, &addr,&sfv);

}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnGetHwInfo 获取硬件信息
 *
 * @param pcontext
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
int32_t OnGetHwInfo(struct tms_context *pcontext)
{
	int32_t ret;
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	tms_RetHwInfo(pcontext, &addr,&HW_INFO);
	return 0;

}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  OnGetHwAlarm 硬件告警
 *
 * @param pcontext
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
int32_t OnGetHwAlarm(struct tms_context *pcontext)
{
	int32_t ret;
	struct glink_addr addr;
	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	//目前无法产生硬件告警，因此硬件告警设置为0
	tms_RetHwAalarm(pcontext, &addr,NULL, 0);
	return 0;

}

int32_t OnClrFiberCfg(struct tms_context *pcontext, struct tms_card_head *pcard_head)
{
	int32_t ret, ch;
	struct glink_addr addr;
	struct tms_ack ack;


	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	ch = pcard_head->pipe;

	memset(&ack, 0, sizeof(ack));
	ack.cmdid = pcontext->pgb->cmdid;

	ret = isValidSlot_Ch(pcard_head->slot, ch);
	if(ret)
		goto usr_exit;


	ret = clr_fiber_sec_para(ch,&chFiberSec[ch], &otdrDev[ch]);
usr_exit:
	ack.errcode = ret;
	tms_AckEx(pcontext->fd, &addr, &ack);
	ret_total_curalarm2host_V2(&addr);

}
int32_t OnGetFiberCfg(struct tms_context *pcontext, struct tms_card_head *pcard_head)
{
	int32_t ret, ch;
	struct glink_addr addr;
	struct tms_ack ack;
	struct tms_fibersectioncfg fiber_cfg;
	struct _tagFiberSecCfg *pfiber_cfg;		//光线段配置参数

	addr.dst = pcontext->pgb->src;
	addr.src = ADDR_LOCAL;
	addr.pkid = pcontext->pgb->pkid;
	ch = pcard_head->pipe;

	memset(&ack, 0, sizeof(ack));
	ack.cmdid = pcontext->pgb->cmdid;

	ret = isValidSlot_Ch(pcard_head->slot, ch);
	if(ret)
		goto usr_exit;
	ret_host_std_cfg(pcontext, &chFiberSec[ch],ch);
usr_exit:
	if(ret != 0){
		ack.errcode = ret;
		tms_AckEx(pcontext->fd, &addr, &ack);
	}

}


void tms_Callback(struct tms_callback *ptcb)
{
	bzero(ptcb, sizeof(struct tms_callback));
	ptcb->pf_OnGetBasicInfo		= OnGetBasicInfo;
	ptcb->pf_OnGetNodeTime		= OnGetNodeTime;
	ptcb->pf_OnRetNodeTime		= OnRetNodeTime;
	ptcb->pf_OnNameAndAddress	= OnNameAndAddress;
	ptcb->pf_OnFiberSectionCfg	= OnFiberSectionCfg;
	ptcb->pf_OnConfigPipeState	= OnConfigPipeState;
	ptcb->pf_OnGetCycleTestCuv	= OnGetCycleTestCuv;
	ptcb->pf_OnGetStatusData	= OnGetStatusData;
	ptcb->pf_OnStatusData		= OnStatusData;
	ptcb->pf_OnCRCCheckout		= OnCRCCheckout;


	ptcb->pf_OnCheckoutResult	= OnCheckoutResult;
	ptcb->pf_OnOTDRBasicInfo	= OnOTDRBasicInfo;
	ptcb->pf_OnConfigNodeTime	= OnConfigNodeTime;
	ptcb->pf_OnCurAlarm		= OnCurAlarm;
	ptcb->pf_OnGetOTDRData		= OnGetOTDRData;
	ptcb->pf_OnGetStandardCurv	= OnGetStandardCurv;


	ptcb->pf_OnGetAllCardType	= NULL;
	ptcb->pf_OnGetSoftv = OnGetSoftv;
	ptcb->pf_OnClrFiberCfg = OnClrFiberCfg;
	ptcb->pf_OnGetFiberCfg = OnGetFiberCfg;
	ptcb->pf_OnGetHwInfo = OnGetHwInfo;
	ptcb->pf_OnGetHwAlarm = OnGetHwAlarm;
	ptcb->pf_OnGetDevType = OnGetDevType;
	ptcb->pf_OnRcvNetSwitch = OnRcvNetSwitch;

	// 70000000
	ptcb->pf_OnSetOCVMPara		= OnSetOCVMPara;
	ptcb->pf_OnSetOCVMFPGAInfo	= OnSetOCVMFPGAInfo;

	// 20000000
	ptcb->pf_OnSetOTDRFPGAInfo	= OnSetOTDRFPGAInfo;
	ptcb->pf_OnGetOTDRFPGAInfo	= OnGetOTDRFPGAInfo;

#ifdef _MANAGE

	// 重定向tms_Analysexxx函数处理方式，如果不执行任何tms_SetDoWhat，则默认表示
	// 协议处于MCU工作方式，回调函数的dowhat设置为0表示不做任何转发，收到的数据一律
	// 传递给应用层
	// 1.作为网管和板卡来说都是传递给应用层
	// 2.作为CU和MCU就要仔细修改dowhat的处理方式
	// int cmd_0xx000xxxx[100];

	// bzero(cmd_0xx000xxxx, sizeof(cmd_0xx000xxxx) / sizeof(int));
	// tms_SetDoWhat(0x10000000, sizeof(cmd_0xx000xxxx) / sizeof(int), cmd_0xx000xxxx);
	// tms_SetDoWhat(0x60000000, sizeof(cmd_0xx000xxxx) / sizeof(int), cmd_0xx000xxxx);
	// tms_SetDoWhat(0x80000000, sizeof(cmd_0xx000xxxx) / sizeof(int), cmd_0xx000xxxx);
#endif

}



#ifdef __cplusplus
}
#endif
